#ifndef __M_HOST_H__
#define __M_HOST_H__
/**
 * @file host.hpp
 * @brief 虚拟机管理模块
 * 
 * 虚拟主机管理类，整合交换器、队列、绑定和消息管理功能
 * 提供虚拟主机级别的消息队列操作接口，包括交换器/队列声明删除、绑定管理、
 * 消息发布消费等核心功能，是消息队列系统的顶层管理单元。
 */
#include "exchange.hpp"
#include "queue.hpp"
#include "binding.hpp"
#include "message.hpp"


namespace bitmq 
{

    /**
     * @class VirtualHost
     * @brief 虚拟主机管理类，整合交换器、队列、绑定和消息管理功能
     * 
     * 提供虚拟主机级别的消息队列操作接口，包括交换器/队列声明删除、绑定管理、
     * 消息发布消费等核心功能，是消息队列系统的顶层管理单元。
     */
    class VirtualHost 
    {
        public:
            using ptr = std::shared_ptr<VirtualHost>;  ///< 智能指针类型定义
            
            /**
             * @brief 构造函数
             * @param hname 虚拟主机名称
             * @param basedir 消息存储基础目录
             * @param dbfile 元数据存储文件路径
             * 
             * 初始化各管理组件并恢复持久化队列的消息数据。
             */
            VirtualHost(const std::string &hname, const std::string &basedir, const std::string &dbfile):
                _host_name(hname),
                _emp(std::make_shared<ExchangeManager>(dbfile)),
                _mqmp(std::make_shared<MsgQueueManager>(dbfile)),
                _bmp(std::make_shared<BindingManager>(dbfile)),
                _mmp(std::make_shared<MessageManager>(basedir)) 
            {
                // 获取所有队列信息并恢复历史消息
                QueueMap qm = _mqmp->allQueues();
                for (auto &q : qm) 
                {
                    _mmp->initQueueMessage(q.first);
                }
            }
            
            /**
             * @brief 声明交换器
             * @param name 交换器名称
             * @param type 交换器类型
             * @param durable 是否持久化
             * @param auto_delete 是否自动删除
             * @param args 附加参数
             * @return 声明成功返回true，否则返回false
             */
            bool declareExchange(const std::string &name,
                ExchangeType type, bool durable, bool auto_delete,
                const google::protobuf::Map<std::string, std::string> &args) 
            {
                return _emp->declareExchange(name, type, durable, auto_delete, args);
            }
            
            /**
             * @brief 删除交换器
             * @param name 交换器名称
             * 
             * 同时删除与该交换器相关的所有绑定关系。
             */
            void deleteExchange(const std::string &name) 
            {
                // 删除交换器前先清理相关绑定
                _bmp->removeExchangeBindings(name);
                return _emp->deleteExchange(name);
            }
            
            /**
             * @brief 检查交换器是否存在
             * @param name 交换器名称
             * @return 存在返回true，否则返回false
             */
            bool existsExchange(const std::string &name) 
            {
                return _emp->exists(name);
            }
            
            /**
             * @brief 获取交换器指针
             * @param ename 交换器名称
             * @return 交换器智能指针，不存在返回空指针
             */
            Exchange::ptr selectExchange(const std::string &ename) 
            {
                return _emp->selectExchange(ename);
            }

            /**
             * @brief 声明队列
             * @param qname 队列名称
             * @param qdurable 是否持久化
             * @param qexclusive 是否排他
             * @param qauto_delete 是否自动删除
             * @param qargs 附加参数
             * @return 声明成功返回true，否则返回false
             * 
             * 同时初始化队列的消息存储管理。
             */
            bool declareQueue(const std::string &qname, 
                bool qdurable, 
                bool qexclusive,
                bool qauto_delete,
                const google::protobuf::Map<std::string, std::string> &qargs) 
            {
                // 初始化队列消息存储
                _mmp->initQueueMessage(qname);
                return _mqmp->declareQueue(qname, qdurable, qexclusive, qauto_delete, qargs);
            }
            
            /**
             * @brief 删除队列
             * @param name 队列名称
             * 
             * 同时删除队列相关的消息数据和绑定关系。
             */
            void deleteQueue(const std::string &name) 
            {
                // 清理队列相关数据：消息存储和绑定关系
                _mmp->destroyQueueMessage(name);
                _bmp->removeMsgQueueBindings(name);
                return _mqmp->deleteQueue(name);
            }
            
            /**
             * @brief 检查队列是否存在
             * @param name 队列名称
             * @return 存在返回true，否则返回false
             */
            bool existsQueue(const std::string &name) 
            {
                return _mqmp->exists(name);
            }
            
            /**
             * @brief 获取所有队列信息
             * @return 队列名称到队列对象的映射表
             */
            QueueMap allQueues() 
            {
                return _mqmp->allQueues();
            }

            /**
             * @brief 绑定队列到交换器
             * @param ename 交换器名称
             * @param qname 队列名称
             * @param key 路由键
             * @return 绑定成功返回true，否则返回false
             */
            bool bind(const std::string &ename, const std::string &qname, const std::string &key) 
            {
                Exchange::ptr ep = _emp->selectExchange(ename);
                if (ep.get() == nullptr) 
                {
                    DLOG("进行队列绑定失败，交换机%s不存在！", ename.c_str());
                    return false;
                }
                MsgQueue::ptr mqp = _mqmp->selectQueue(qname);
                if (mqp.get() == nullptr) 
                {
                    DLOG("进行队列绑定失败，队列%s不存在！", qname.c_str());
                    return false;
                }
                return _bmp->bind(ename, qname, key, ep->durable && mqp->durable);
            }
            
            /**
             * @brief 解除队列与交换器的绑定
             * @param ename 交换器名称
             * @param qname 队列名称
             */
            void unBind(const std::string &ename, const std::string &qname) 
            {
                return _bmp->unBind(ename, qname);
            }
            
            /**
             * @brief 获取交换器的绑定关系
             * @param ename 交换器名称
             * @return 交换器绑定关系映射表
             */
            MsgQueueBindingMap exchangeBindings(const std::string &ename) 
            {
                return _bmp->getExchangeBindings(ename);
            }
            
            /**
             * @brief 检查绑定关系是否存在
             * @param ename 交换器名称
             * @param qname 队列名称
             * @return 存在返回true，否则返回false
             */
            bool existsBinding(const std::string &ename, const std::string &qname) 
            {
                return _bmp->exists(ename, qname);
            }

            /**
             * @brief 发布消息到队列
             * @param qname 队列名称
             * @param bp 消息属性
             * @param body 消息内容
             * @return 发布成功返回true，否则返回false
             */
            bool basicPublish(const std::string &qname, BasicProperties *bp, const std::string &body) 
            {
                MsgQueue::ptr mqp = _mqmp->selectQueue(qname);
                if (mqp.get() == nullptr)
                {
                    DLOG("发布消息失败，队列%s不存在！", qname.c_str());
                    return false;
                }
                return _mmp->insert(qname, bp, body, mqp->durable);
            }
            
            /**
             * @brief 从队列消费消息
             * @param qname 队列名称
             * @return 消息指针，队列为空返回空指针
             */
            MessagePtr basicConsume(const std::string &qname) 
            {
                return _mmp->front(qname);
            }
            
            /**
             * @brief 确认消息已被处理
             * @param qname 队列名称
             * @param msgid 消息ID
             */
            void basicAck(const std::string &qname, const std::string &msgid) 
            {
                return _mmp->ack(qname, msgid);
            }  
            
            /**
             * @brief 清空虚拟主机所有数据
             * 
             * 包括交换器、队列、绑定关系和消息数据。
             */
            void clear() 
            {
                _emp->clear();
                _mqmp->clear();
                _bmp->clear();
                _mmp->clear();
            } 
        private:
            std::string _host_name;          ///< 虚拟主机名称
            ExchangeManager::ptr _emp;       ///< 交换器管理器
            MsgQueueManager::ptr _mqmp;      ///< 队列管理器
            BindingManager::ptr _bmp;        ///< 绑定关系管理器
            MessageManager::ptr _mmp;        ///< 消息管理器
    };
}

#endif